<!--
    文件名: exampleOfCarousel_demo.html
    描述: 这是一个轮播图示例，用于展示如何使用JavaScript和CSS创建一个简单的轮播图。
    作者: 周雪松
    创建日期: 2025-01-25
    修改日期: 2025-01-26
-->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>轮播图示例</title>
    <style>
        .carousel {
            width: 80%;
            margin: auto;
            overflow: hidden;
            position: relative;
        }
        .carousel-inner {
            display: flex;
            transition: transform 0.5s ease-in-out; /* 平滑过渡效果 */
        }
        .carousel-item {
            min-width: 100%;
            box-sizing: border-box;
        }
        .carousel-item img {
            width: 100%;
            height: auto; /* 保持图片的宽高比 */
            display: block;
        }
        .carousel-control {
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            background: rgba(0, 0, 0, 0.5);
            color: white;
            border: none;
            padding: 10px;
            cursor: pointer;
        }
        .carousel-control.prev {
            left: 10px;
        }
        .carousel-control.next {
            right: 10px;
        }
    </style>
</head>
<body>
<div id="carousel" class="carousel">
    <div class="carousel-inner">
        <!-- 图片将通过JavaScript动态生成 -->
    </div>
    <button class="carousel-control prev">&#10094;</button>
    <button class="carousel-control next">&#10095;</button>
</div>

<script>
    // 将所有逻辑封装到一个函数中
    function initializeCarousel() {
        // 轮播图配置
        const carouselConfig = {
            imageNames: ['img_1.png', 'img_2.png', 'img_3.png'], // 图片名称数组
            imageBasePath: 'images_01', // 图片基础路径
            autoPlayInterval: 3000 // 切换图片的时间间隔，单位为毫秒
        };

        // 轮播图雷
        class Carousel {
            constructor(carouselElement, imageNames, imageBasePath, autoPlayInterval) {
                this.carouselElement = carouselElement; // 轮播图容器元素
                this.carouselInner = carouselElement.querySelector('.carousel-inner'); // 轮播图内部容器
                this.imageNames = imageNames; // 图片名称数组
                this.imageBasePath = imageBasePath; // 图片基础路径
                this.autoPlayInterval = autoPlayInterval; // 自动播放间隔时间
                this.totalItems = imageNames.length; // 图片总数
                this.currentIndex = 0; // 当前显示的图片索引
                this.prevButton = carouselElement.querySelector('.carousel-control.prev'); // 上一张按钮
                this.nextButton = carouselElement.querySelector('.carousel-control.next'); // 下一张按钮
                this._init(); // 初始化轮播图
            }

            // 私有方法：初始化轮播图
            _init() {
                this._createImages(); // 动态创建图片元素
                this._showSlide(this.currentIndex); // 显示初始图片
                this._bindEvents(); // 绑定按钮事件
                this._autoPlay(); // 启动自动播放
            }

            // 私有方法：动态创建图片元素
            _createImages() {
                // 克隆最后一张图片并添加到开头
                const lastItemClone = this.carouselInner.lastElementChild?.cloneNode(true) || document.createElement('div');
                this.carouselInner.insertBefore(lastItemClone, this.carouselInner.firstElementChild);

                this.imageNames.forEach((imageName, index) => {
                    const item = document.createElement('div'); // 创建轮播项容器
                    item.classList.add('carousel-item'); // 添加类名
                    const img = document.createElement('img'); // 创建图片元素
                    img.src = `${this.imageBasePath}/${imageName}`; // 设置图片路径
                    img.alt = `Slide ${index + 1}`; // 设置图片alt属性
                    item.appendChild(img); // 将图片添加到轮播项容器中
                    this.carouselInner.appendChild(item); // 将轮播项容器添加到轮播图内部容器中
                });

                // 克隆第一张图片并添加到末尾
                const firstItemClone = this.carouselInner.firstElementChild.cloneNode(true);
                this.carouselInner.appendChild(firstItemClone);
            }

            // 私有方法：显示指定索引的图片
            _showSlide(index) {
                if (index < 0) {
                    this.currentIndex = this.totalItems - 1; // 如果索引小于0，显示最后一张图片
                    this.carouselInner.style.transition = 'none'; // 禁用过渡效果
                    this.carouselInner.style.transform = `translateX(-${this.totalItems * 100}%)`; // 设置到克隆的最后一张图片的位置
                    void this.carouselInner.offsetWidth; // 强制重绘
                    requestAnimationFrame(() => {
                        this.carouselInner.style.transition = 'transform 0.5s ease-in-out'; // 启用过渡效果
                        this.carouselInner.style.transform = `translateX(-${this.currentIndex * 100}%)`; // 设置到实际的最后一张图片的位置
                    });
                } else if (index >= this.totalItems) {
                    this.currentIndex = 0; // 如果索引大于等于图片总数，显示第一张图片
                    this.carouselInner.style.transition = 'transform 0.5s ease-in-out'; // 确保过渡效果
                    this.carouselInner.style.transform = `translateX(-${this.totalItems * 100}%)`; // 设置到克隆的第一张图片的位置
                    void this.carouselInner.offsetWidth; // 强制重绘
                    requestAnimationFrame(() => {
                        this.carouselInner.style.transition = 'none'; // 禁用过渡效果
                        this.carouselInner.style.transform = `translateX(0%)`; // 设置到实际的第一张图片的位置
                        void this.carouselInner.offsetWidth; // 强制重绘
                        this.carouselInner.style.transition = 'transform 0.5s ease-in-out'; // 重新启用过渡效果
                    });
                } else {
                    this.currentIndex = index; // 设置当前索引
                    const offset = -this.currentIndex * 100; // 计算偏移量
                    this.carouselInner.style.transition = 'transform 0.5s ease-in-out'; // 确保过渡效果
                    requestAnimationFrame(() => {
                        this.carouselInner.style.transform = `translateX(${offset}%)`; // 设置偏移量
                    });
                }
            }

            // 公共方法：切换到下一张图片
            nextSlide() {
                this._showSlide(this.currentIndex + 1);
            }

            // 公共方法：切换到上一张图片
            prevSlide() {
                this._showSlide(this.currentIndex - 1);
            }

            // 私有方法：绑定按钮事件
            _bindEvents() {
                this.prevButton.addEventListener('click', () => this.prevSlide()); // 绑定上一张按钮事件
                this.nextButton.addEventListener('click', () => this.nextSlide()); // 绑定下一张按钮事件
            }

            // 私有方法：启动自动播放
            _autoPlay() {
                setInterval(() => this.nextSlide(), this.autoPlayInterval); // 使用配置中的时间间隔
            }
        }

        // 创建轮播图实例
        const carouselElement = document.getElementById('carousel'); // 获取轮播图容器元素
        const carousel = new Carousel(carouselElement, carouselConfig.imageNames, carouselConfig.imageBasePath, carouselConfig.autoPlayInterval); // 创建 Carousel 实例
    }

    // 页面加载完成后执行初始化函数
    window.onload = initializeCarousel;
</script>
</body>
</html>